package com.meida.module.admin.provider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.meida.common.constants.CommonConstants;
import com.meida.common.enums.StateEnum;
import com.meida.common.exception.OpenAlertException;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.mybatis.model.DeleteModel;
import com.meida.common.mybatis.model.PageParams;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.model.UpdateModel;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.security.OpenAuthority;
import com.meida.common.security.OpenHelper;
import com.meida.common.security.SecurityConstants;
import com.meida.common.utils.ApiAssert;
import com.meida.common.utils.FlymeUtils;
import com.meida.common.utils.StringUtils;
import com.meida.module.admin.client.constants.BaseConstants;
import com.meida.module.admin.client.entity.BaseRole;
import com.meida.module.admin.client.entity.BaseUser;
import com.meida.module.admin.client.model.UserInfo;
import com.meida.module.admin.provider.mapper.BaseUserMapper;
import com.meida.module.admin.provider.service.BaseAuthorityService;
import com.meida.module.admin.provider.service.BaseRoleService;
import com.meida.module.admin.provider.service.BaseUserAccountService;
import com.meida.module.admin.provider.service.BaseUserService;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.cloud.bus.BusProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * @author: zyf
 * @date: 2018/10/24 16:33
 * @description:
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, BaseUser> implements BaseUserService {

    @Autowired
    private BaseUserMapper baseUserMapper;
    @Autowired
    private BaseRoleService roleService;
    @Resource
    private AutowireCapableBeanFactory spring;
    @Autowired
    private BaseAuthorityService baseAuthorityService;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private ApplicationEventPublisher publisher;
    @Autowired
    private BusProperties busProperties;

    @Autowired
    private BaseUserAccountService userAccountService;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private BaseUserAccountService baseUserAccountService;

    private final String ACCOUNT_DOMAIN = BaseConstants.ACCOUNT_DOMAIN_ADMIN;

    /**
     * 更新系统用户
     *
     * @param baseUser
     * @return
     */
    @Override
    public void addUser(BaseUser baseUser) {
        if (getUserByUsername(baseUser.getUserName()) != null) {
            throw new OpenAlertException("用户名:" + baseUser.getUserName() + "已存在!");
        }
        //保存系统用户信息
        baseUserMapper.insert(baseUser);
        //默认注册用户名账户
        baseUserAccountService.register(baseUser.getUserId(), baseUser.getUserName(), baseUser.getPassword(), BaseConstants.USER_ACCOUNT_TYPE_USERNAME, baseUser.getStatus(), ACCOUNT_DOMAIN, null);
        if (StringUtils.matchEmail(baseUser.getEmail())) {
            //注册email账号登陆
            baseUserAccountService.register(baseUser.getUserId(), baseUser.getEmail(), baseUser.getPassword(), BaseConstants.USER_ACCOUNT_TYPE_EMAIL, baseUser.getStatus(), ACCOUNT_DOMAIN, null);
        }
        if (StringUtils.matchMobile(baseUser.getMobile())) {
            //注册手机号账号登陆
            baseUserAccountService.register(baseUser.getUserId(), baseUser.getMobile(), baseUser.getPassword(), BaseConstants.USER_ACCOUNT_TYPE_MOBILE, baseUser.getStatus(), ACCOUNT_DOMAIN, null);
        }
    }

    /**
     * 更新系统用户
     *
     * @param model
     * @return
     */
    @Override
    public ResultBody updateUser(UpdateModel model) {
        Long userId = model.getId();
        ApiAssert.isNotEmpty("userId不能为空", userId);
        CriteriaUpdate<BaseUser> cu = new CriteriaUpdate(model, BaseUser.class);
        BaseUser user = cu.getEntity(BaseUser.class);
        return baseEdit(cu, user);
    }

    /**
     * 分页查询
     *
     * @param map
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody pageList(Map map) {
        CriteriaQuery<BaseUser> cq = new CriteriaQuery(map, BaseUser.class);
        PageParams pageParams = cq.getPageParams();
        BaseUser query = cq.getEntity(BaseUser.class);
        cq.lambda()
                .eq(FlymeUtils.isNotEmpty(query.getUserId()), BaseUser::getUserId, query.getUserId())
                .eq(FlymeUtils.isNotEmpty(query.getUserType()), BaseUser::getUserType, query.getUserType())
                .eq(FlymeUtils.isNotEmpty(query.getUserName()), BaseUser::getUserName, query.getUserName())
                .like(FlymeUtils.isNotEmpty(query.getNickName()), BaseUser::getNickName, query.getNickName())
                .eq(FlymeUtils.isNotEmpty(query.getMobile()), BaseUser::getMobile, query.getMobile())
                .ge(FlymeUtils.isNotEmpty(pageParams.getBeginDate()), BaseUser::getRegisterTime, pageParams.getBeginDate())
                .le(FlymeUtils.isNotEmpty(pageParams.getEndDate()), BaseUser::getRegisterTime, pageParams.getEndDate())
                .eq(FlymeUtils.isNotEmpty(query.getStatus()), BaseUser::getStatus, query.getStatus());
        cq.orderByDesc("createTime");
        return basePageList(cq);
    }

    /**
     * 查询列表
     *
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<BaseUser> findAllList() {
        List<BaseUser> list = baseUserMapper.selectList(new QueryWrapper<>());
        return list;
    }

    /**
     * 依据系统用户Id查询系统用户信息
     *
     * @param userId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public BaseUser getUserById(Long userId) {
        return baseUserMapper.selectById(userId);
    }

    /**
     * 根据用户ID获取用户信息和权限
     *
     * @param userId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public UserInfo getUserWithAuthoritiesById(Long userId) {
        // 用户权限列表
        List<OpenAuthority> authorities = Lists.newArrayList();
        // 用户角色列表
        List<Map> roles = Lists.newArrayList();
        List<BaseRole> rolesList = roleService.getUserRoles(userId);
        if (rolesList != null) {
            for (BaseRole role : rolesList) {
                Map roleMap = Maps.newHashMap();
                roleMap.put("roleId", role.getRoleId());
                roleMap.put("roleCode", role.getRoleCode());
                roleMap.put("roleName", role.getRoleName());
                // 用户角色详情
                roles.add(roleMap);
                // 加入角色标识
                OpenAuthority authority = new OpenAuthority(role.getRoleId().toString(), SecurityConstants.AUTHORITY_PREFIX_ROLE + role.getRoleCode(), null, "role");
                authorities.add(authority);
            }
        }

        //查询系统用户资料
        BaseUser baseUser = getUserById(userId);

        // 加入用户权限
        List<OpenAuthority> userGrantedAuthority = baseAuthorityService.findAuthorityByUser(userId, CommonConstants.ROOT.equals(baseUser.getUserName()));
        if (userGrantedAuthority != null && userGrantedAuthority.size() > 0) {
            authorities.addAll(userGrantedAuthority);
        }
        UserInfo userProfile = new UserInfo();
        BeanUtils.copyProperties(baseUser, userProfile);

        //设置用户资料,权限信息
        userProfile.setAuthorities(authorities);
        userProfile.setRoles(roles);
        return userProfile;
    }


    /**
     * 依据登录名查询系统用户信息
     *
     * @param username
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public BaseUser getUserByUsername(String username) {
        QueryWrapper<BaseUser> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(BaseUser::getUserName, username);
        BaseUser saved = baseUserMapper.selectOne(queryWrapper);
        return saved;
    }

    /**
     * 设置用户状态
     *
     * @param userId
     * @return
     */
    @Override
    public ResultBody setStatus(Long userId) {
        ResultBody resultBody = new ResultBody();
        BaseUser user = baseUserMapper.selectById(userId);
        Integer stateEnum = user.getStatus();
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.eq("userId", userId);
        if (stateEnum.equals(StateEnum.ENABLE.getCode())) {
            cu.set(true, "status", StateEnum.DISABLE.getCode());
            resultBody.setMsg(StateEnum.DISABLE.getName() + "成功").data(false);
        } else {
            cu.set(true, "status", StateEnum.ENABLE.getCode());
            resultBody.setMsg(StateEnum.ENABLE.getName() + "成功").data(true);
        }
        update(cu);
        return resultBody;

    }

    @Override
    public ResultBody delete(DeleteModel model) {
        CriteriaDelete cd = new CriteriaDelete(model, BaseUser.class);
        Long userId = OpenHelper.getUserId();
        Long[] userIds = model.getIds();
        if (!FlymeUtils.contains(userIds, userId)) {
            baseUserAccountService.removeAccount(userIds);
        } else {
            return ResultBody.failed("禁止删除当前用户");
        }
        return baseDelete(cd);
    }

}
